<template>
	<form class="px-[35px]" @submit.prevent="onEnter">
		<input type="submit" class="hidden" />
		<base-icon
			v-if="!accountStore.isLogin"
			name="back2"
			class="text-[20px] absolute left-3 top-3 cursor-pointer"
			@click="onBack" />
		<base-icon
			name="close"
			class="text-[20px] absolute right-3 top-3 cursor-pointer"
			@click="onClose" />
		<div class="h-12 mt-[50px] mb-4 pt-[12px] app-font-bold text-center text-[20px]">
			{{ $t('reset.setNewPassword') }}
		</div>
		<base-tip class="mb-4" textT="reset.step3Title" />
		<base-input
			labelT="reset.password"
			placeholderT="reset.step3Title"
			type="password"
			v-model="formValue.password"
			:name="FormFieldName.passwordNew"
			:autofocus="isPC()"
			:rules="formRule.password.result.rules"
			:is-danger="!formRule.password.result.valid"
			@blur="formRule.password.validator()"
			@focus="formReset('password')" />
		<base-input
			labelT="reset.password2"
			placeholderT="reset.password2"
			type="password"
			v-model="formValue.password2"
			:name="FormFieldName.passwordNewConfirm"
			:error-t="formRule.password2.result.textT"
			:is-danger="!formRule.password2.result.valid"
			@blur="formRule.password2.validator()"
			@focus="formReset('password2')" />
		<base-button type="primary" :loading="loading" @click="onEnter">
			{{ $t('reset.submit') }}
		</base-button>
	</form>
</template>

<script setup lang="ts">
import { resetPassword } from '@/api/account'
import { BaseButton, BaseIcon, BaseInput, BaseTip } from '@/components/base'
import { computed, nextTick, reactive, ref } from 'vue'
import { FormFieldName } from '@/enums'
import { useDialog } from '@/hooks'
import { useAccountStore } from '@/store'
import { AccountShowType, Action } from '@/types'
import { hasSpace, isLength, isPC } from '@/utils'
import { useMessage } from '@/hooks/'
import { RuleType } from '@/views/account/welcome/register.vue'

const message = useMessage()
const accountStore = useAccountStore()
const formValue = reactive({
	password: '',
	password2: ''
})
const formRule = reactive({
	password: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.password.result = { valid: true })
			if (action === Action.input) formRule.password.hasInput = true
			if (action === Action.blur && !formRule.password.hasInput) return
			const value = formValue.password
			const spaceValid = !!value && !hasSpace(value)
			const rules = [
				{ textT: 'register.passwordRuleLength', valid: isLength(value, 8, 24) && spaceValid },
				{ textT: 'register.passwordRuleChar', valid: /[a-zA-Z]/.test(value) },
				{ textT: 'register.passwordRuleNum', valid: /[0-9]/.test(value) }
			]
			formRule.password.result = { valid: rules.every(({ valid }) => valid), rules }
		}
	},
	password2: {
		hasInput: false,
		result: <RuleType>{ valid: true },
		validator: (action?: Action) => {
			if (action === Action.reset) return (formRule.password2.result = { valid: true })
			if (action === Action.input) formRule.password2.hasInput = true
			if (action === Action.blur && !formRule.password2.hasInput) return
			const value = formValue.password2
			let msg = ''
			if (value !== formValue.password) {
				msg = 'reset.password2NoMatch'
			}
			formRule.password2.result = { textT: msg, valid: !msg }
		}
	}
})

const formReset = (field: keyof typeof formRule, withValue: boolean = false) => {
	if (withValue && formValue[field]) formValue[field] = ''
	nextTick(() => {
		formRule[field]?.hasInput && (formRule[field].hasInput = false)
		formRule[field]?.validator?.(Action.reset)
	})
}

const onBack = () => accountStore.showAccount(AccountShowType.login)
const onClose = () => accountStore.showAccount(AccountShowType.none)

const loading = ref(false)

const submitDisabled = computed(
	() =>
		!formValue.password ||
		!formValue.password2 ||
		formValue.password !== formValue.password2 ||
		Object.values(formRule).some(({ result: { valid } }) => !valid)
)

const onSubmit = async () => {
	try {
		loading.value = true
		await resetPassword({
			token: accountStore.resetToken,
			newPassword: formValue.password.trim(),
			confirmPassword: formValue.password2.trim()
		})
		loading.value = false
		onSuccess()
	} catch (err) {
		loading.value = false
		message.error(err)
	}
}

const onSuccess = () => {
	useDialog().success({
		titleT: 'tip.success',
		contentT: 'reset.success',
		cancelShow: false,
		closeFn: () => {
			accountStore.clearLoginInfo()
			accountStore.showAccount(AccountShowType.login)
		}
	})
}

const onEnter = () => {
	if (loading.value) return
	Object.values(formRule).forEach(({ validator }) => validator(Action.submit))
	nextTick(() => {
		if (submitDisabled.value) return
		onSubmit()
	})
}
</script>
